﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;

namespace IsDroneApp
{


    public class StateObject
    {
        public Socket workSocket = null;
        public const int BufferSize = 1024;
        public byte[] buffer = new byte[BufferSize];
        public StringBuilder sb = new StringBuilder();
    }
   
    public class Server
    {
        public List<Socket> _clients;
        public  ManualResetEvent allDone = new ManualResetEvent(false);
       

        public void SetState(StateDrone state)
        {
            foreach (var c in _clients)
            {
                if (c.Connected)
                    Send(c,  state.ToString());
            }
        }

        public void SetDate(byte[] date)
        {

            foreach (var c in _clients)
            {
                if (c.Connected)
                {
                   
               
                    Send(c,"start", date);
                }
            }
        }


        public  void StartListening( object port)
        {
            
            _clients = new List<Socket>();
           var name= Dns.GetHostName();
            var ipHostInfo = Dns.GetHostAddresses(name);
            IPEndPoint localEndPoint = new IPEndPoint(ipHostInfo[0], (int)port);
            Socket listener = new Socket(AddressFamily.InterNetwork,
                SocketType.Stream, ProtocolType.Tcp);
            try
            {
                listener.Bind(localEndPoint);
                listener.Listen(100);
                while (true)
                {
                    allDone.Reset();
                    Console.WriteLine("Waiting for a connection...");
                    listener.BeginAccept(
                        AcceptCallback,
                        listener);
                  //  allDone.WaitOne();
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e.ToString());
            }
        }

        public  void AcceptCallback(IAsyncResult ar)
        {
          //  allDone.Set();
            Socket listener = (Socket) ar.AsyncState;
            Socket handler = listener.EndAccept(ar);
            _clients.Add(handler);
        }

        private  void Send(Socket handler, String data)
        {
            try
            {
                byte[] byteData = Encoding.ASCII.GetBytes(data);
                handler.BeginSend(byteData, 0, byteData.Length, 0,
                    new AsyncCallback(SendCallback), handler);
            }
            catch
            { }
        }

        bool sends = false;
        private void Send(Socket handler, String data, byte[] d)
        {
            try
            {
               
                {

                    handler.SendTimeout = 30;
                    byte[] byteData = Encoding.ASCII.GetBytes(data).Concat(d).ToArray();
                    sends = true;
                handler.BeginSend(byteData, 0, byteData.Length, 0,
                    new AsyncCallback(SendCallback2), handler);
                }
            }
            catch
            { }
        }


        private void Send(Socket handler, byte[] data)
        {
            try
            {
                if (!handler.Blocking)
                {
                    handler.SendTimeout = 30;
                    handler.BeginSend(data, 0, data.Length, 0,
                        new AsyncCallback(SendCallback), handler);
                }
            }
            catch
            { }
        }

        private void SendCallback2(IAsyncResult ar)
        {
            try
            {
                Socket handler = (Socket)ar.AsyncState;
                handler.EndSend(ar);
                sends = false;
            }
            catch (Exception e)
            {
                Console.WriteLine(e.ToString());
            }
        }

        private  void SendCallback(IAsyncResult ar)
        {
            try
            {
                Socket handler = (Socket) ar.AsyncState;
              handler.EndSend(ar);
              
            }
            catch (Exception e)
            {
                Console.WriteLine(e.ToString());
            }
        }
    }

}
